#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
package ${package}.common.utils;

import ${package}.common.bean.po.Role;
import ${package}.common.bean.po.User;
import ${package}.common.bean.vo.SecurityUser;
import ${package}.common.component.service.SpringContext;
import ${package}.common.emum.ReturnCodeEnum;
import ${package}.common.exception.SessionException;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;

/**
 * Description: 获取当前登录的用户及其角色
 *
 * @author wupanhua
 * @date 2019/8/6 15:28
 *
 * <pre>
 *              ${copyright}
 *      Copyright (c) 2019. All Rights Reserved.
 * </pre>
 */
public class SessionUtil {

    /**
     * 验证头
     */
    private static final String TOKEN_HEADER = "Authorization";
    /**
     * 验证类型
     */
    private static final String AUTH_TYPE = "Bearer ";

    /**
     * 工具类无法被实例化
     */
    private SessionUtil(){}

    /**
     * Description:
     * <获取到request类>
     * @author wupanhua
     * @date 14:08 2020-04-13
     * @return javax.servlet.http.HttpServletRequest
     **/
    private static HttpServletRequest getHttpServletRequest() {
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert sra != null;
        return sra.getRequest();
    }

    /**
     * Description:
     * <获取到AuthorizationServerTokenServices类，此类存储了用户登陆信息>
     * @author wupanhua
     * @date 14:09 2020-04-13
     * @return org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices
     **/
    private static AuthorizationServerTokenServices getAuthorizationServerTokenServices() {
        return SpringContext.getBean("authorizationServerTokenServices", AuthorizationServerTokenServices.class);
    }

    /**
     * Description:
     * <获取当前登录用户>
     * @author wupanhua
     * @date 15:47 2019/8/8
     * @return User
     **/
    public static User getUser() {

        SecurityUser securityUser = getSecurityUser();
        User user = new User();
        if(null!=securityUser) {
            BeanUtils.copyProperties(securityUser, user);
        }
        return user;
    }

    /**
     * Description:
     * <获取当前登录用户的角色>
     * @author wupanhua
     * @date 15:48 2019/8/8
     * @return java.util.List<Role>
     **/
    public static List<Role> getRoles() {

        return getUser().getRoleArrayList();
    }

    /**
     * Description:
     * <获取当前登陆用户的uri权限列表>
     * @author wupanhua
     * @date 12:03 2019-09-02

     * @return java.util.List<java.lang.String>
     */
    public static List<String> getUri() {

        SecurityUser securityUser = getSecurityUser();
        if(null == securityUser.getPermissionUri()){
            return Lists.newArrayList();
        }else{
            return (Objects.isNull(securityUser) || CollectionUtils.isEmpty(securityUser.getPermissionUri()))
                    ? Lists.newArrayList() : securityUser.getPermissionUri();
        }
    }

    private static SecurityUser getSecurityUser() {
        String token = getHttpServletRequest().getHeader(TOKEN_HEADER);
        token = token.substring(AUTH_TYPE.length());
        if (StringUtils.isEmpty(token)) {
            return null;
        }

        DefaultTokenServices defaultTokenServices = (DefaultTokenServices) getAuthorizationServerTokenServices();
        OAuth2Authentication oAuth2Authentication = defaultTokenServices.loadAuthentication(token);
        if (Objects.isNull(oAuth2Authentication)) {
            throw new SessionException(ReturnCodeEnum.USER_NOT_IN_SESSION);
        }

        Object object = oAuth2Authentication.getPrincipal();
        return (SecurityUser) object;
    }

    /**
     * Description:
     * <移除缓存中的数据>
     * @author wupanhua
     * @date 15:48 2019/8/8
     **/
    public static void removeSession() {

        String token = getHttpServletRequest().getHeader(TOKEN_HEADER);
        token = token.substring(AUTH_TYPE.length());
        if (StringUtils.isEmpty(token)) {
            return ;
        }

        DefaultTokenServices defaultTokenServices = (DefaultTokenServices) getAuthorizationServerTokenServices();
        defaultTokenServices.revokeToken(token);
    }

}
